<?php

namespace addons\wdsxh\library;

use EasyWeChat\Factory;
use think\Exception;
use think\Log;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Pool;
use GuzzleHttp\Exception\ClientException;

/**
 * 微信处理类
 */
class Wxapp
{
    public static function wxappInit($type = 0)
    {
        try {
            $site = (new \app\admin\model\wdsxh\Config())->where('id',1)->find();
            if (empty($site['appid'])) {
                throw new \think\Exception('小程序AppID未配置');
            }
            if (empty($site['secret'])) {
                throw new \think\Exception('小程序AppSecret未配置');
            }
            if ($type == 1) {
                if (empty($site['mch_id'])) {
                    throw new \think\Exception('微信支付商户号未配置');
                }
                if (empty($site['key'])) {
                    throw new \think\Exception('微信支付秘钥未配置');
                }
            }
            $config = [
                'app_id' => trim($site['appid']),
                'secret' => trim($site['secret']),
                'mch_id' => empty($site['mch_id']) ? '' : trim($site['mch_id']),
                'key' => empty($site['key']) ? '' : trim($site['key']),
                'cert_path' => empty($site['cert_path']) ? '' : ROOT_PATH . 'public' . trim($site['cert_path']),
                'key_path' => empty($site['key_path']) ? '' : ROOT_PATH . 'public' . trim($site['key_path']),
                'notify_url' => '',
                'response_type' => 'array',
                'log' => [
                    'level' => 'debug',
                    'file' => RUNTIME_PATH . 'wechat.log',
                ],
            ];
            if ($type == 0) {
                return Factory::miniProgram($config);
            } else {
                return Factory::payment($config);
            }
        } catch (Exception $e) {
            die($e->getMessage());
        }
    }

    public static function getApp()
    {
        return self::wxappInit();
    }

    public static function getPay()
    {
        return self::wxappInit(1);
    }

    public static function wxlogin($code)
    {
        return self::getApp()->auth->session($code);
    }

    public static function unify($body, $sn, $money, $openid, $notify_url)
    {
        $pay = self::getPay();
        $result = $pay->order->unify([
            'body' => $body,
            'out_trade_no' => $sn,
            'total_fee' => $money * 100,
            'notify_url' => $notify_url,
            'trade_type' => 'JSAPI',
            'openid' => $openid,
        ]);
        if ($result && $result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS' && isset($result['prepay_id'])) {
            return $pay->jssdk->bridgeConfig($result['prepay_id'], false);
        } else {
            Log::record([
                'body' => $body,
                'out_trade_no' => $sn,
                'total_fee' => $money * 100,
                'notify_url' => $notify_url,
                'trade_type' => 'JSAPI',
                'openid' => $openid,
            ], 'info');
            Log::record($result, 'info');
            throw new \think\Exception(isset($result['return_msg']) ? $result['return_msg'] : '统一下单发生错误');
        }
    }

    /*
     * 退款操作
     */
    public static function payRefund($number, $refundNumber, $refundFee, $config = null)
    {
        $pay = self::getPay();
        try {
            $result = $pay->refund->byOutTradeNumber($number, $refundNumber, intval($refundFee * 100), intval($refundFee * 100), $config ? $config : [
                'refund_desc' => '支付后退款',
            ]);
        } catch (\Exception $e) {
            die($e->getMessage());
        }
        return $result;
    }

    public static function phone($code, $iv, $encryptedData)
    {
        $app = self::getApp();
        $openid = $app->auth->session($code);
        if (empty($openid['openid']) || empty($openid['session_key'])) {
            throw new \think\Exception('小程序登录失败');
        }
        return $app->encryptor->decryptData($openid['session_key'], $iv, $encryptedData);
    }

    public static function getQrcode($path)
    {
        $app = self::getApp();
        $response = $app->app_code->get($path, array('width' => 280, 'is_hyaline' => true));
        //$response = $app->app_code->getQrCode($path,280);
        if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
            $savePath = ROOT_PATH . 'public' . DS . 'uploads'.DS.'wdsxh'.DS.'qrcode' . DS;
            if (!is_dir($savePath)) {
                mkdir($savePath, 0777, true);
            }
            $filename = time() . mt_rand(1000, 9999) . '.png';
            $response->saveAs($savePath, $filename);
            return $savePath . $filename;
        }
        return false;
    }

    public static function subscribeMessage($template_id, $openid, $page = '', $data)
    {
        if(empty($template_id) || empty($openid) || empty($data)){
            return false;
        }
        $app = self::getApp();
        $accessToken = $app->access_token;
        $token = $accessToken->getToken(true);
        $url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={$token['access_token']}";
        $content = [
            'template_id' => trim($template_id),
            'touser' => '',
            'page' => trim($page),
            'data' => $data,
        ];
        //$response=$app->subscribe_message->send($data);
        $client = new Client();
        $openids = [];
        if (is_string($openid)) {
            $openids[] = $openid;
        } elseif (is_array($openid)) {
            $openids = $openid;
        } else {
            throw new Exception('openid类型错误');
        }
        try {
            $requests = function ($total) use ($client, $url, $content, $openids) {
                foreach ($openids as $row) {
                    $content['touser'] = $row;
                    yield function () use ($client, $url, $content) {
                        $options = [
                            'headers' => ['Content-Type' => 'application/json'],
                            'body' => json_encode($content)
                        ];
                        return $client->postAsync($url, $options);
                    };
                }
            };
            $res = [];
            $pool = new Pool($client, $requests(count($openids)), [
                'concurrency' => count($openids),
                'fulfilled' => function ($response, $index) use (&$res) {
                    $res[$index] = json_decode($response->getBody()->getContents(), true);
                },
                'rejected' => function ($reason, $index) use (&$res) {
                    $res[$index] = $reason;
                },
            ]);
            $promise = $pool->promise();
            $promise->wait();
        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        } catch (ClientException $e) {
            throw new Exception($e->getMessage());
        }
        return $res;
    }

    public static function uniformSend($openid, $mp_template_msg)
    {
        $app = self::getApp();
        $accessToken = $app->access_token;
        $token = $accessToken->getToken();
        //$token['access_token']='52_63X_eM5aNEhZzOf3Xnv6rRCJuRNRfFzusXQTxaXy1AojDMnEFfxykrl1gPWK4EmYVh8DnawA8tPH1ojEVbFJBjwHpfezDJGwCk5K6b-r__fNMr0GsdIt8IivO3n_fi3ZQVXyFhgn4z2bB3uaSCXeAGAFPK';
        $url = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=' . $token['access_token'];
        $data = [
            'touser' => $openid,
            'mp_template_msg' => $mp_template_msg
        ];
        $response = self::httpPost($url, $data);

    }

    /**
     * Author: ELk
     * Date: 2024-04-23 15:20:33
     * @ApiTitle : 内容安全验证
     * @ApiParams int $openid
     * @ApiParams int $scene 场景枚举值（1 资料；2 评论；3 论坛；4 社交日志）
     * @ApiParams string $content 需检测的文本内容，文本字数的上限为2500字，需使用UTF-8编码
    */
    static public function msgSecCheck($openid, $scene, $content)
    {
        $app = self::getApp();
        $accessToken = $app->access_token;
        $token = $accessToken->getToken();
        $url = 'https://api.weixin.qq.com/wxa/msg_sec_check?access_token=' . $token['access_token'];
        $data = [
            'openid' => $openid,
            'version' => 2,
            'scene' => $scene,
            'content' => $content,
        ];
        switch ($scene) {
            case 1:
                $data['nickname'] = $content;
                break;
        }
        $response = self::httpPost($url, $data);
        $response_arr = json_decode($response, true);
        if($response_arr['errcode'] == 0) {
            if($response_arr['result']['label'] > 100) {
                return false;
            }
        }
        return true;
    }

    private static function httpPost($url, $data)
    {
        $curlPost = json_encode($data);
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_NOBODY, true);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);
        $return_str = curl_exec($curl);
        curl_close($curl);
        return $return_str;
    }

}
